https://azure.microsoft.com/ko-kr/services/cognitive-services/
- 디렉토리 : https://azure.microsoft.com/ko-kr/services/cognitive-services/directory/vision/
- 메모리 사용용량은 4MB
- 외부라이브러리 사용시 제약 있을 수 있다.
이 자습서를 사용하려면 다음을 수행해야 합니다.
- Python 2.7+ 또는 Python 3.5+ 중 하나를 설치합니다.
- pip를 설치합니다.
- 다음과 같이 Face API용 Python SDK를 설치합니다.
bash pip install cognitive_face- Microsoft Cognitive Services에 대한 구독 키를 구합니다. 이 자습서의 주 또는 보조 키를 사용할 수 있습니다. (Face API를 사용하려면 유효한 구독 키가 있어야 합니다.)
Face
markdown
Detect, identify, analyze, organize, and tag faces in photos
30,000 transactions, 20 per minute.
Endpoint: https://westcentralus.api.cognitive.microsoft.com/face/v1.0
Key 1: 4f7ec58767f64cd391de86fbb7f8b410
Key 2: 54ca95aea4784eae8aa6c1764ffdd241
https://docs.microsoft.com/ko-kr/azure/cognitive-services/emotion/quickstarts/python
- Face API는 이제 감정 인식을 통합하여, 이미지에 있는 각 얼굴의 분노, 경멸, 혐오, 공포, 행복, 무표정, 슬픔, 놀람 같은 일련의 감정을 확실하게 인식합니다.
- 이러한 감정은 특정 얼굴 표정으로 서로 다른 문화에서 보편적으로 전달되는 것으로 이해되고 있습니다.
이 연습을 계속하려면 subscription_key를 앞에서 받은 API 키로 바꿉니다.
# python code
subscription_key = None
assert subscription_key
Face API를 추가로 탐색하는 데 도움이 되도록 이 자습서는 GUI 예제를 제공합니다.
이를 실행하려면 먼저 wxPython을 설치한 후 아래 명령을 실행합니다.
[bash]
git clone https://github.com/Microsoft/Cognitive-Face-Python.git
cd Cognitive-Face-Python
python sample
다음으로, 서비스 URL이 API 키를 설정할 때 사용한 지역과 일치하는지 확인합니다. 평가판 키를 사용하는 경우 아무 것도 변경할 필요가 없습니다.
emotion_recognition_url = "https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize"
이미지 데이터는 요청 본문의 일부로 전달되므로 Content-Type 헤더를 application/octet-stream으로 설정해야 합니다. URL을 통해 이미지를 전달하는 경우 다음과 같이 헤더를 설정합니다.
header = {'Ocp-Apim-Subscription-Key': subscription_key }
해당 URL을 포함하는 사전을 만들도록 설정:
data = {'url': image_url}
다음을 사용하여 requests 라이브러리에 전달:
requests.post(emotion_recognition_url, headers=headers, json=image_data)
먼저 Emotion API 사이트에서 몇 가지 샘플 이미지를 다운로드합니다.
%%bash
mkdir -p images
curl -Ls https://aka.ms/csnb-emotion-1 -o images/emotion_1.jpg
curl -Ls https://aka.ms/csnb-emotion-2 -o images/emotion_2.jpg
Python Code
image_path = "images/emotion_1.jpg"
image_data = open(image_path, "rb").read()
import requests
headers = {'Ocp-Apim-Subscription-Key': subscription_key, "Content-Type": "application/octet-stream" }
response = requests.post(emotion_recognition_url, headers=headers, data=image_data)
response.raise_for_status()
analysis = response.json()
analysis
반환된 JSON 개체에는 감지된 감정과 함께 인식된 얼굴의 경계 상자가 포함됩니다.
각 감정은 0~1 사이의 점수와 연결되며 점수가 높을수록 감정이 직설적입니다.
[{'faceRectangle': {'height': 162, 'left': 130, 'top': 141, 'width': 162},
'scores': {'anger': 9.29041e-06,
'contempt': 0.000118981574,
'disgust': 3.15619363e-05,
'fear': 0.000589638,
'happiness': 0.06630674,
'neutral': 0.00555004273,
'sadness': 7.44669524e-06,
'surprise': 0.9273863}}]
다음 코드 줄은 matplotlib 라이브러리를 사용하여 이미지의 얼굴에 드러난 감정을 감지했습니다. 혼잡을 방지하기 위해 상위 3개 감정만 표시됩니다.
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from io import BytesIO
from PIL import Image
plt.figure(figsize=(5,5))
image = Image.open(BytesIO(image_data))
ax = plt.imshow(image, alpha=0.6)
for face in analysis:
fr = face["faceRectangle"]
em = face["scores"]
origin = (fr["left"], fr["top"])
p = Rectangle(origin, fr["width"], fr["height"], fill=False, linewidth=2, color='b')
ax.axes.add_patch(p)
ct = "\n".join(["{0:<10s}{1:>.4f}".format(k,v) for k, v in sorted(list(em.items()),key=lambda r: r[1], reverse=True)][:3])
plt.text(origin[0], origin[1], ct, fontsize=20)
_ = plt.axis("off")
그 다음으로 표시되는 annotate_image 함수는 파일 시스템에 경로가 지정된 이미지 파일 위에 감정을 오버레이하는 데 사용할 수 있습니다. 앞에서 살펴본 Emotion API를 호출하는 코드를 기반으로 합니다.
def annotate_image(image_path):
image_data = open(image_path, "rb").read()
headers = {'Ocp-Apim-Subscription-Key': subscription_key, "Content-Type": "application/octet-stream" }
response = requests.post(emotion_recognition_url, headers=headers, data=image_data)
response.raise_for_status()
analysis = response.json()
plt.figure()
image = Image.open(image_path)
ax = plt.imshow(image, alpha=0.6)
for face in analysis:
fr = face["faceRectangle"]
em = face["scores"]
origin = (fr["left"], fr["top"])
p = Rectangle(origin, fr["width"], fr["height"], fill=False, linewidth=2, color='b')
ax.axes.add_patch(p)
ct = "\n".join(["{0:<10s}{1:>.4f}".format(k,v) for k, v in sorted(list(em.items()),key=lambda r: r[1], reverse=True)][:3])
plt.text(origin[0], origin[1], ct, fontsize=20, va="bottom")
_ = plt.axis("off")
마지막으로, annotate_image 함수는 다음 줄에 보여드리는 것처럼 이미지 파일에서 호출할 수 있습니다.
annotate_image("images/emotion_2.jpg")
# endpoint = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0'
# subscription_key1 = '4f7ec58767f64cd391de86fbb7f8b410'
# subscription_key2 = '54ca95aea4784eae8aa6c1764ffdd241'
# base_url = endpoint
# subscription_key = subscription_key1
# 자신의 사용자 API를 등록
base_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0'
subscription_key = '********************************'
# endpoint + detect
face_api_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect'
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import requests
def downloadImage(image_url):
face_image = requests.get(image_url)
img = Image.open(BytesIO(face_image.content))
return img
# 테스트에 사용할 이미지 : 응답하라 1997
image_url = 'http://i.imgur.com/UcVb2YQ.jpg'
img = downloadImage(image_url)
img
headers = {'Ocp-Apim-Subscription-key':subscription_key}
headers
data = {'url':image_url}
data
params = {
'returnFacdId' : 'true',
'returnFaceLandmarks' : 'false',
'returnFaceAttributes' : 'emotion'
}
# requests.post(face_api_url, params=params, headers=headers, json=data)
Signature: requests.post(url, data=None, json=None, **kwargs)
Docstring:
Sends a POST request.
response = requests.post(face_api_url, params=params, headers=headers, json=data)
response
faces = response.json()
faces
import cognitive_face as CF
# 테스트에 사용할 이미지 : 응답하라 1988
image_url = 'https://i.ytimg.com/vi/rxfxrrSfbnk/maxresdefault.jpg'
img = downloadImage(image_url)
img
KEY = subscription_key # Replace with a valid subscription key (keeping the quotes in place).
CF.Key.set(KEY)
BASE_URL = 'https://westus.api.cognitive.microsoft.com/face/v1.0/' # Replace with your regional Base URL
CF.BaseUrl.set(endpoint)
faces = CF.face.detect(image_url)
faces
headers = {'Ocp-Apim-Subscription-key':subscription_key}
headers
# 속성값 추가
faceAttributes = 'age,gender,headPose,smile,facialHair,glasses,' \
+ 'emotion,hair,makeup,occlusion,accessories,' \
+ 'blur,exposure,noise'
faceAttributes
params = {
'returnFacdId' : 'true',
'returnFaceLandmarks' : 'false',
'returnFaceAttributes' : faceAttributes
}
params
data = {'url':image_url}
data
response = requests.post(face_api_url, params=params, headers=headers, json=data)
response
faces = response.json()
faces
# endpoint = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0'
# subscription_key1 = '4f7ec58767f64cd391de86fbb7f8b410'
# subscription_key2 = '54ca95aea4784eae8aa6c1764ffdd241'
# base_url = endpoint
# subscription_key = subscription_key1
# face_api_url = 'https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect'
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
# face_api_url = 'https://japaneast.api.cognitive.microsoft.com/face/v1.0/detect'
# subscription_key = 'c7415e098dc045698a07d4171b69ba46'
# headers = {'Ocp-Apim-Subscription-key':subscription_key}
def getFaceEmotion(image_url):
params = {
'returnFacdId' : 'true',
'returnFaceLandmarks' : 'false',
'returnFaceAttributes' : 'emotion'
}
data = {'url':image_url}
response = requests.post(face_api_url, params=params, headers=headers, json=data)
faces = response.json()
print(faces[0]['faceAttributes']['emotion'])
# face_image = requests.get(image_url)
# img = Image.open(BytesIO(face_image.content))
return faces
# 테스트에 사용할 이미지 : 응답하라 1988
image_url = 'https://i.ytimg.com/vi/zIZV204WBq8/maxresdefault.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
faces
# 분노, 경멸, 역겨움, 두려움, 행복, 중립, 슬픔, 놀람
def getFaceEmotion(image_url):
data = {'url':image_url}
response = requests.post(face_api_url, params=params, headers=headers, json=data)
faces = response.json()
attributes = {'anger': '분노', 'contempt': '경멸', 'disgust': '역겨움', 'fear': '두려움',
'happiness': '행복', 'neutral': '중립', 'sadness': '슬픔', 'surprise': '놀람'}
emotion = faces[0]['faceAttributes']['emotion']
# print(emotion)
result = '# 얼굴감성분석 결과 \n'
result+= '{a_key}:{a_val} | {c_key}:{c_val} | {d_key}:{d_val} | {f_key}:{f_val} | '
result+= '{h_key}:{h_val} | {n_key}:{n_val} | {sd_key}:{sd_val} | {sp_key}:{sp_val} '
result = result.format(
a_key = attributes['anger'], a_val = emotion['anger'],
c_key = attributes['contempt'], c_val = emotion['contempt'],
d_key = attributes['disgust'], d_val = emotion['disgust'],
f_key = attributes['fear'], f_val = emotion['fear'],
h_key = attributes['happiness'], h_val = emotion['happiness'],
n_key = attributes['neutral'], n_val = emotion['neutral'],
sd_key = attributes['sadness'], sd_val = emotion['sadness'],
sp_key = attributes['surprise'], sp_val = emotion['surprise'],
)
print(result)
# face_image = requests.get(image_url)
# img = Image.open(BytesIO(face_image.content))
return emotion
# 테스트에 사용할 이미지 : 응답하라 1994
image_url = 'https://taejun.files.wordpress.com/2013/10/ec9d91eb8bb5ed9598eb9dbc-1994_2.jpg'
img = downloadImage(image_url)
img
emotion = getFaceEmotion(image_url)
emotion
# 분노, 경멸, 역겨움, 두려움, 행복, 중립, 슬픔, 놀람
def getFaceEmotion(image_url):
data = {'url':image_url}
response = requests.post(face_api_url, params=params, headers=headers, json=data)
faces = response.json()
attributes = {'anger': '분노', 'contempt': '경멸', 'disgust': '역겨움', 'fear': '두려움',
'happiness': '행복', 'neutral': '중립', 'sadness': '슬픔', 'surprise': '놀람'}
emotion = faces[0]['faceAttributes']['emotion']
# print(emotion)
result = '# 얼굴감성분석 결과 \n'
result+= '{a_key}:{a_val}% | {c_key}:{c_val}% | {d_key}:{d_val}% | {f_key}:{f_val}% | '
result+= '{h_key}:{h_val}% | {n_key}:{n_val}% | {sd_key}:{sd_val}% | {sp_key}:{sp_val}% '
result = result.format(
a_key = attributes['anger'], a_val = 100*emotion['anger'],
c_key = attributes['contempt'], c_val = 100*emotion['contempt'],
d_key = attributes['disgust'], d_val = 100*emotion['disgust'],
f_key = attributes['fear'], f_val = 100*emotion['fear'],
h_key = attributes['happiness'], h_val = 100*emotion['happiness'],
n_key = attributes['neutral'], n_val = 100*emotion['neutral'],
sd_key = attributes['sadness'], sd_val = 100*emotion['sadness'],
sp_key = attributes['surprise'], sp_val = 100*emotion['surprise'],
)
print(result)
# face_image = requests.get(image_url)
# img = Image.open(BytesIO(face_image.content))
return emotion
# 테스트에 사용할 이미지 : 응답하라 1994
image_url = 'http://i.imgur.com/Cu1lVMD.jpg'
img = downloadImage(image_url)
img
emotion = getFaceEmotion(image_url)
emotion
# 분노, 경멸, 역겨움, 두려움, 행복, 중립, 슬픔, 놀람
def getFaceEmotion(image_url):
data = {'url':image_url}
response = requests.post(face_api_url, params=params, headers=headers, json=data)
faces = response.json()
faces_cnt = len(faces)
if faces_cnt > 1:
print('Face count :', faces_cnt)
attributes = {'anger': '분노', 'contempt': '경멸', 'disgust': '역겨움', 'fear': '두려움',
'happiness': '행복', 'neutral': '중립', 'sadness': '슬픔', 'surprise': '놀람'}
emotion = faces[0]['faceAttributes']['emotion']
result = '# 얼굴감성분석 결과 \n'
result+= '{a_key}:{a_val}% | {c_key}:{c_val}% | {d_key}:{d_val}% | {f_key}:{f_val}% | '
result+= '{h_key}:{h_val}% | {n_key}:{n_val}% | {sd_key}:{sd_val}% | {sp_key}:{sp_val}% '
result = result.format(
a_key = attributes['anger'], a_val = int(100*emotion['anger']*10)/10,
c_key = attributes['contempt'], c_val = int(100*emotion['contempt']*10)/10,
d_key = attributes['disgust'], d_val = int(100*emotion['disgust']*10)/10,
f_key = attributes['fear'], f_val = int(100*emotion['fear']*10)/10,
h_key = attributes['happiness'], h_val = int(100*emotion['happiness']*10)/10,
n_key = attributes['neutral'], n_val = int(100*emotion['neutral']*10)/10,
sd_key = attributes['sadness'], sd_val = int(100*emotion['sadness']*10)/10,
sp_key = attributes['surprise'], sp_val = int(100*emotion['surprise']*10)/10,
)
print(result)
# face_image = requests.get(image_url)
# img = Image.open(BytesIO(face_image.content))
return emotion
# 테스트에 사용할 이미지 : 준영이 페북
image_url = 'https://scontent-hkg3-2.xx.fbcdn.net/v/t31.0-8/13147508_1546592955635797_3511714954759328670_o.jpg?_nc_cat=0&oh=56769ad1f05bf090c46ff3e04f72ad6d&oe=5C1676AA'
img = downloadImage(image_url)
img
emotion = getFaceEmotion(image_url)
emotion
# 분노, 경멸, 역겨움, 두려움, 행복, 중립, 슬픔, 놀람
def getFaceEmotion(image_url):
data = {'url':image_url}
response = requests.post(face_api_url, params=params, headers=headers, json=data)
faces = response.json()
faces_cnt = len(faces)
attributes = {'anger': '분노', 'contempt': '경멸', 'disgust': '역겨움', 'fear': '두려움',
'happiness': '행복', 'neutral': '중립', 'sadness': '슬픔', 'surprise': '놀람'}
if faces_cnt > 1:
print('이미지에서 총 {}명의 얼굴이 인식되었습니다.'.format(faces_cnt))
print('-'*125)
for idx in range(faces_cnt):
emotion = faces[idx]['faceAttributes']['emotion']
if faces_cnt > 1:
result = '# 얼굴감성분석 Face{} : '.format(idx+1)
else:
result = '# 얼굴감성분석 결과 \n'
result+= '{a_key}:{a_val}% | {c_key}:{c_val}% | {d_key}:{d_val}% | {f_key}:{f_val}% | '
result+= '{h_key}:{h_val}% | {n_key}:{n_val}% | {sd_key}:{sd_val}% | {sp_key}:{sp_val}% '
result = result.format(
a_key = attributes['anger'], a_val = int(100*emotion['anger']*10)/10,
c_key = attributes['contempt'], c_val = int(100*emotion['contempt']*10)/10,
d_key = attributes['disgust'], d_val = int(100*emotion['disgust']*10)/10,
f_key = attributes['fear'], f_val = int(100*emotion['fear']*10)/10,
h_key = attributes['happiness'], h_val = int(100*emotion['happiness']*10)/10,
n_key = attributes['neutral'], n_val = int(100*emotion['neutral']*10)/10,
sd_key = attributes['sadness'], sd_val = int(100*emotion['sadness']*10)/10,
sp_key = attributes['surprise'], sp_val = int(100*emotion['surprise']*10)/10,
)
print(result)
return faces
# 테스트에 사용할 이미지 : 준영이 페북, 여러명
# image_url = 'https://scontent-hkg3-2.xx.fbcdn.net/v/t1.0-9/523903_241628852622822_2008747604_n.jpg?_nc_cat=0&oh=74063c1811c07d468bbc355ff8a00636&oe=5C221352'
# image_url = 'https://scontent-hkg3-2.xx.fbcdn.net/v/t1.0-9/11159515_1442529932708767_8892475195222993236_n.jpg?_nc_cat=0&oh=3f4c2b92f9d02f0d371621a573517a4a&oe=5C30116E'
# image_url = 'https://scontent-hkg3-2.xx.fbcdn.net/v/t1.0-9/11259810_1442526769375750_2512241092460312870_n.jpg?_nc_cat=0&oh=1a319349c55a1ec93f7f60ab6eb2535d&oe=5C2CDC64'
image_url = 'https://scontent-hkg3-2.xx.fbcdn.net/v/t1.0-9/11061287_1442505689377858_8178191899633104414_n.jpg?_nc_cat=0&oh=7c4371b70b491947650222df9ee4b615&oe=5C3231A7'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
for idx in range(len(faces)):
face = faces[idx]
print('Face{:2} : {}'.format(idx+1, face['faceRectangle']))
def checkFaces(faces):
for idx in range(len(faces)):
face = faces[idx]
print('Face{:2} : {}'.format(idx+1, face['faceRectangle']))
checkFaces(faces)
# 테스트에 사용할 이미지 : 응답하라 1994, 여러명
image_url = 'https://pds.joins.com/news/component/htmlphoto_mmdata/201312/23/htm_20131223172924c010c011.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
checkFaces(faces)
# 테스트에 사용할 이미지
image_url = 'https://data.photo-ac.com/data/thumbnails/70/70dd494971829e620e1a6517e5ba14c8_t.jpeg'
img = downloadImage(image_url);
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://archivenew.vop.co.kr/images/bbf303ed004e1f9c8ada8c0c817ef8a9/2014-05/marked/19095213_3.JPG'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://pds.joins.com/news/component/htmlphoto_mmdata/201704/22/a45c187c-4ddd-4530-a72a-7959fcab83c2.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://i1.media.daumcdn.net/uf/image/U01/agora/5588B18C41337D000A'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://pds7.egloos.com/pds/200805/19/95/f0034395_4831491c9a38d.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://mblogthumb4.phinf.naver.net/20160828_231/p9573198_1472384723899Mk6PH_JPEG/%B3%EB%B9%AB%C7%F6_%B8%B7%B0%C9%B8%AE_%B8%B6%BD%C3%B4%C2_%B8%F0%BD%C0.jpg?type=w2'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'https://ncache.ilbe.com/files/attach/new/20170810/377678/5416762468/9952977732/fbbaa02895972bec7917d62f10f03d6e.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'https://img.huffingtonpost.com/asset/5b1f80942200003000eeb2fb.jpeg?cache=Wv4BtCV53D&ops=scalefit_630_noupscale'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
checkFaces(faces)
# 테스트에 사용할 이미지
image_url = 'http://dimg.donga.com/wps/NEWS/IMAGE/2009/04/03/7120331.1.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'https://t1.daumcdn.net/thumb/R1280x0/?fname=http://t1.daumcdn.net/brunch/service/user/Jp6/image/fj9A21x9sD7J-sXmxFdYQEiqEo8.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://cfile10.uf.tistory.com/image/26317F3553A7CE6E340FB6'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)
# 테스트에 사용할 이미지
image_url = 'http://image.chosun.com/sitedata/image/201807/04/2018070404475_0.jpg'
img = downloadImage(image_url)
img
faces = getFaceEmotion(image_url)